<?php

namespace app\common\command;

use app\common\service\TxService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Db;
use think\facade\Log;

class CheckInvestmentStatus extends Command
{
    // USDT ERC20 合约地址（以太坊主网）
    const USDT_CONTRACT = '0xdac17f958d2ee523a2206206994597c13d831ec7';
    // Transfer Event Hash
    const TRANSFER_EVENT = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';

    protected function configure()
    {
        $this->setName('check_investment_status')
            ->setDescription('定时检查用户投资充值与赎回状态（基于链上 tx_hash 确认）');
    }

    protected function execute(Input $input, Output $output)
    {
        $now = date('Y-m-d H:i:s');
        $output->writeln("[$now] 开始执行投资状态检查...");

        $txService = new TxService();
        $processedCount = 0;

        try {
            // =====================================================
            // 1. 检查 status=0（待确认）的记录 → 是否已成功充值
            // =====================================================
            $pendingList = Db::name('user_investment')
                ->where('status', 0)
                ->whereNotNull('tx_hash')
                ->where('tx_hash', '<>', '')
                ->field('id, user_id, tx_hash, address, usdt_amount, invest_time, create_time')
                ->select();

            $output->writeln("🔍 发现 " . count($pendingList) . " 条待确认的投资记录");

            foreach ($pendingList as $item) {
                $output->writeln("  → 检查 #{$item['id']}, tx: {$item['tx_hash']}");

                try {
                    $txData = $txService->getTransaction($item['tx_hash']);
                    if (!$txData) {
                        $output->writeln("    ⚠️ 未查到交易数据，跳过");
                        continue;
                    }

                    // 交易必须成功
                    if (empty($txData['status']) || $txData['status'] != 1) {
                        $output->writeln("    ❌ 交易失败或未确认");
                        continue;
                    }

                    // 验证 USDT 是否到账（金额 + 地址）
//                    $isDepositValid = $this->verifyUsdtDeposit($txData, $item['address'], $item['usdt_amount']);
                    $isDepositValid = false;

                    if($txData['success'] && strtolower($txData['from']) == $item['address']) {
                        $isDepositValid = true;
                    }

                    if ($isDepositValid) {
                        // ✅ 充值成功，激活投资
                        Db::name('user_investment')->where('id', $item['id'])->update([
                            'status' => 1,
                            'last_profit_time' => $item['invest_time'], // 从投资时间开始计息
                            'update_time' => time(),
                            'remark' => '链上确认：充值成功，状态激活'
                        ]);

                        $output->writeln("    ✅ 投资 #{$item['id']} 激活成功！用户: {$item['user_id']}");
                        $processedCount++;

                        // 可选：触发通知、记录日志、开始收益计算等
                        $this->onInvestmentActivated($item['id'], $item['user_id']);

                    } else {
                        $output->writeln("    ❌ 验证失败：未检测到有效 USDT 充值");
                    }

                } catch (\Exception $e) {
                    Log::error('检查充值状态失败', [
                        'investment_id' => $item['id'],
                        'tx_hash' => $item['tx_hash'],
                        'error' => $e->getMessage()
                    ]);
                    $output->writeln("    ❗ 处理异常: " . $e->getMessage());
                }

                usleep(200000); // 控制请求频率
            }

            // =====================================================
            // 2. 检查 status=2（已赎回）但 close_time 为空的记录
            // =====================================================
            $redeemingList = Db::name('user_investment')
                ->where('status', 4)
                ->whereNotNull('close_tx_hash')
                ->where('close_tx_hash', '<>', '')
                ->field('id, user_id, close_tx_hash')
                ->select();

            $output->writeln("🔍 发现 " . count($redeemingList) . " 条待确认赎回的记录");

            foreach ($redeemingList as $item) {
                $output->writeln("  → 检查赎回 #{$item['id']}, tx: {$item['close_tx_hash']}");

                try {
                    $txData = $txService->getTransaction($item['close_tx_hash']);

                    if (!$txData) {
                        $output->writeln("    ⚠️ 未查到赎回交易数据");
                        continue;
                    }

                    $isSuccess = false;

                    if($txData['success'] && strtolower($txData['from']) == $item['address']) {
                        $isSuccess = true;
                    }

                    if ($isSuccess) {
                        Db::name('user_investment')->where('id', $item['id'])->update([
                            'close_time' => time(),
                            'update_time' => time(),
                            'remark' => '链上确认：赎回交易成功',
                            'status' => 2
                        ]);

                        $output->writeln("    ✅ 赎回 #{$item['id']} 确认成功！");
                        $processedCount++;
                    } else {
                        $output->writeln("    ❌ 赎回交易失败或未确认");
                    }

                } catch (\Exception $e) {
                    Log::error('检查赎回状态失败', [
                        'investment_id' => $item['id'],
                        'error' => $e->getMessage()
                    ]);
                }

                usleep(200000);
            }

        } catch (\Exception $e) {
            Log::critical('CheckInvestmentStatus 执行异常', ['error' => $e->getMessage()]);
            $output->writeln("❗️ 任务执行出错: " . $e->getMessage());
            return 1;
        }

        $output->writeln("✅ 任务完成！共处理 $processedCount 条记录。");
        return 0;
    }

    /**
     * 验证 USDT 充值是否到账
     */
    private function verifyUsdtDeposit(array $txData, string $toAddress, float $expectedAmount): bool
    {
        if (empty($txData['receipt']['logs'])) return false;

        foreach ($txData['receipt']['logs'] as $log) {
//            // 1. 合约地址匹配
//            if (strtolower($log['address'] ?? '') !== strtolower(self::USDT_CONTRACT)) {
//                continue;
//            }
//
//            // 2. 事件类型匹配
//            if (empty($log['topics'][0]) || strtolower($log['topics'][0]) !== strtolower(self::TRANSFER_EVENT)) {
//                continue;
//            }

            // 3. 接收地址匹配
            if (empty($log['topics'][2])) continue;
            $logTo = '0x' . substr($log['topics'][2], 26);
            if (strtolower($logTo) !== strtolower($toAddress)) {
                continue;
            }

            // 4. 金额验证（宽松匹配）
            if (!empty($log['data'])) {
                $logValue = hexdec(ltrim($log['data'], '0x')) / 1_000_000; // USDT 精度为 6
                $diff = abs($logValue - $expectedAmount);
                if ($diff > 0.01) { // 容差 1 分 USDT
                    return false;
                }
            }

            return true; // 地址对了就认为有效
        }

        return false;
    }

    /**
     * 投资激活后的钩子函数（可扩展）
     */
    private function onInvestmentActivated(int $investmentId, int $userId)
    {
        // 例如：发送通知、记录用户行为、触发收益计算队列等
        // event('InvestmentActivated', ['investment_id' => $investmentId, 'user_id' => $userId]);
    }
}